//
// Created by cmo on 2022/5/13.
//

#include "util.h"

JavaVM* g_vm= NULL;

extern "C" {
//1、C++代码 若无参数需要传递，JNIEnv *env, jobject jobj可省，若传递参数必须
void dynamic(JNIEnv *env, jobject jobj) {
    LOGE("dynamicRegister 已动态注册到dynamic（无参数）");
}
void dynamic2(JNIEnv *env, jobject jobj, jint i) {
    LOGE("dynamicRegister2 已动态注册dynamic（%d）", i);
}

//2、定义一个JNINativeMethod数组用于保存Java代码中对应的native方法
//typedef struct {//jni.h这JNINativeMethod包含三部分：{Java层的方法名，方法签名，（void*）本地方法名}
//    const char *name;
//    const char *signature;
//    void *funPtr;
//} JNINativeMethod;

//2、需要动态注册的方法数组,这JNINativeMethod包含三部分：{Java层的方法名，方法签名，(返回值*)本地方法名,}）
static const JNINativeMethod mMethods[] = {
        {"dynamicRegister", "()V",  (void *) dynamic},
        {"dynamicRegister", "(I)V", (void *) dynamic2}
};

//3、需要动态注册native方法的Java类名（.改为/）
static const char *mJavaClzName = "com/crazymo/jni/DynamicRegisterJNI";

//重写JNI_OnLoad

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    LOGE("JNI_OnLoad run");
    g_vm=vm;
    JNIEnv *env = 0;
    //从vm中获取JNIEnv指针
    int ret = vm->GetEnv((void **) &env, JNI_VERSION_1_6);
    if (ret != JNI_OK) {
        LOGE("unSupport jni version");
        return -1;
    }
    //反射获取Java层的Class，这个类不能被混淆，所有有Native方法的类都不能混淆
    jclass jclz = env->FindClass(mJavaClzName);
    ret = env->RegisterNatives(jclz, mMethods, sizeof(mMethods) / sizeof(JNINativeMethod));
    if (ret != JNI_OK) {
        LOGE("dynamic register jni failed");
        return -1;
    }
    return JNI_VERSION_1_6;
}
}